/**
 * ProfileService - 人物/企业档案核心服务
 * 
 * 功能：
 * 1. 从基准数据（公安个人信息/廉政档案）创建档案
 * 2. 从业务数据（银行流水/话单等）关联到档案
 * 3. 查询和搜索档案
 */

const { IDCardCleaner } = require('./cleaners');

class ProfileService {
    /**
     * 从基准数据创建或更新人物档案
     * @param {Object} knex - 案件数据库连接
     * @param {Object} data - 人物数据
     * @param {Object} options - 选项
     */
    static async createOrUpdateProfile(knex, data, options = {}) {
        const {
            entity_type = 'person',
            id_card,
            credit_code,
            name,
            gender,
            birth_date,
            province,
            photo_path,
            phones,
            accounts,
            addresses,
            extra_data,
            source_table,
            source_id,
            tags
        } = data;

        // 1. 尝试基于核心标识（身份证/统一信用代码）构建搜索条件
        let searchIdCard = null;
        let searchCreditCode = null;

        if (entity_type === 'person' && id_card) {
            const cleaned = IDCardCleaner.clean(id_card);
            // 即使校验不通过，如果格式勉强符合，也尝试使用
            if (cleaned) {
                searchIdCard = cleaned;
            } else if (/^[\dXx]{15,18}$/.test(id_card)) {
                searchIdCard = id_card.trim().toUpperCase();
            }

            // 尝试从身份证补全信息
            if (searchIdCard) {
                const parsed = IDCardCleaner.parse(searchIdCard);
                if (parsed.valid || parsed.birthYear) {
                    data.gender = data.gender || parsed.gender;
                    data.birth_date = data.birth_date || parsed.birthday;
                    data.province = data.province || parsed.province;
                }
            }
        } else if (entity_type === 'company' && credit_code) {
            searchCreditCode = credit_code.trim().toUpperCase();
        }

        // 2. 查找现有档案 (Multi-pass Search)
        // Pass 1: ID Card / Credit Code (Strongest)
        let existing = null;
        if (searchIdCard) {
            existing = await knex('profile_entities').where('id_card', searchIdCard).first();
        } else if (searchCreditCode) {
            existing = await knex('profile_entities').where('credit_code', searchCreditCode).first();
        }

        // Pass 2: Phone Number (Medium) - Only if not found by ID and phone is available
        if (!existing && entity_type === 'person' && phones && phones.length > 0) {
            const phoneList = Array.isArray(phones) ? phones : [phones];
            const firstPhone = phoneList[0]; // 简化：只匹配第一个手机号
            // 模糊匹配 phones 数组字段
            const matches = await knex('profile_entities')
                .where('entity_type', 'person')
                .whereRaw('phones LIKE ?', [`%${firstPhone}%`])
                .orderBy('updated_at', 'desc') // 取最近更新的
                .limit(1);

            if (matches && matches.length > 0) {
                existing = matches[0];
                // 验证：如果是依靠手机号匹配到的，需要确认姓名是否冲突
                // 如果库里叫 "张三"，新数据叫 "李四"，同一个手机号，可能是复用
                // 这种情况下是否合并？保守策略：姓名相同时才合并，或者库里没有姓名
                if (existing.name && name && existing.name !== name) {
                    console.warn(`[ProfileService] Phone match ${firstPhone} but name mismatch: ${existing.name} vs ${name}. Skipping merge.`);
                    existing = null; // 拒绝合并
                } else {
                    console.log(`[ProfileService] Matched by phone: ${firstPhone}`);
                }
            }
        }

        // 确定最终使用的标识符 (用于新建)
        // 如果没有 searchIdCard/Code, 我们需要一个标识符. 
        // 方案：生成一个 uuid 或者使用 "PHONE|138..." 临时标识
        // 但数据库 id_card/credit_code 是字段。
        // 我们需要由 profile_entities.id 主键来唯一标识。
        // "coreIdentifier" 变量之前用于 log 和检查，现在逻辑稍微变了。

        if (!existing) {
            // 只有当有 强标识(IdCard/CreditCode) 或者 有效的弱标识(Phone + Name) 时才创建
            // 如果仅有 Name，不创建
            const hasStrongId = !!searchIdCard || !!searchCreditCode;
            const hasWeakId = (phones && phones.length > 0) && name; // 手机号+姓名

            if (!hasStrongId && !hasWeakId) {
                // console.warn('[ProfileService] Insufficient identity data to create profile');
                return null;
            }
        }

        if (existing) {
            // 更新现有档案（合并信息）
            const updates = {
                updated_at: knex.fn.now()
            };

            // 仅更新非空字段
            if (name && !existing.name) updates.name = name;
            if (data.gender && !existing.gender) updates.gender = data.gender;
            if (data.birth_date && !existing.birth_date) updates.birth_date = data.birth_date;
            if (data.province && !existing.province) updates.province = data.province;
            if (photo_path && !existing.photo_path) updates.photo_path = photo_path;

            // 重要：如果现有档案没有身份证，但新数据有，则补全 (Identity Merging/Upgrade)
            if (!existing.id_card && searchIdCard) {
                updates.id_card = searchIdCard;
                console.log(`[ProfileService] Upgrading profile #${existing.id} with ID Card: ${searchIdCard}`);
            }
            if (!existing.credit_code && searchCreditCode) {
                updates.credit_code = searchCreditCode;
            }

            // 合并数组字段
            if (phones) {
                const existingPhones = JSON.parse(existing.phones || '[]');
                const newPhones = Array.isArray(phones) ? phones : [phones];
                const mergedPhones = [...new Set([...existingPhones, ...newPhones])];
                updates.phones = JSON.stringify(mergedPhones);
            }

            if (accounts) {
                const existingAccounts = JSON.parse(existing.accounts || '[]');
                const newAccounts = Array.isArray(accounts) ? accounts : [accounts];
                const mergedAccounts = [...new Set([...existingAccounts, ...newAccounts])];
                updates.accounts = JSON.stringify(mergedAccounts);
            }

            if (addresses) {
                const existingAddresses = JSON.parse(existing.addresses || '[]');
                const newAddresses = Array.isArray(addresses) ? addresses : [addresses];
                const mergedAddresses = [...new Set([...existingAddresses, ...newAddresses])];
                updates.addresses = JSON.stringify(mergedAddresses);
            }

            // 合并extra_data
            if (extra_data) {
                const existingExtra = JSON.parse(existing.extra_data || '{}');
                const newExtra = typeof extra_data === 'string' ? JSON.parse(extra_data) : extra_data;
                updates.extra_data = JSON.stringify({ ...existingExtra, ...newExtra });
            }

            await knex('profile_entities')
                .where('id', existing.id)
                .update(updates);

            console.log(`[ProfileService] Updated profile #${existing.id} for ${searchIdCard || existing.id_card || name}`);
            return existing.id;
        } else {
            // 创建新档案
            const insertData = {
                entity_type,
                name,
                id_card: searchIdCard, // 优先使用清洗后的
                credit_code: searchCreditCode,
                gender: data.gender,
                birth_date: data.birth_date,
                province: data.province,
                photo_path,
                phones: phones ? JSON.stringify(Array.isArray(phones) ? phones : [phones]) : '[]',
                accounts: accounts ? JSON.stringify(Array.isArray(accounts) ? accounts : [accounts]) : '[]',
                addresses: addresses ? JSON.stringify(Array.isArray(addresses) ? addresses : [addresses]) : '[]',
                extra_data: extra_data ? (typeof extra_data === 'string' ? extra_data : JSON.stringify(extra_data)) : '{}',
                source_table,
                source_id,
                tags: tags ? JSON.stringify(Array.isArray(tags) ? tags : [tags]) : '[]'
            };

            const [id] = await knex('profile_entities').insert(insertData);
            console.log(`[ProfileService] Created profile #${id} (${searchIdCard || name})`);
            return id;
        }
    }

    /**
     * 通过身份证号查找档案
     */
    static async findByIdCard(knex, idCard) {
        const cleanedIdCard = IDCardCleaner.clean(idCard);
        if (!cleanedIdCard) return null;

        return await knex('profile_entities')
            .where('id_card', cleanedIdCard)
            .first();
    }

    /**
     * 通过企业统一社会信用代码查找档案
     */
    static async findByCreditCode(knex, creditCode) {
        if (!creditCode) return null;

        return await knex('profile_entities')
            .where('credit_code', creditCode.trim().toUpperCase())
            .first();
    }

    /**
     * 通过任意标识查找档案
     * @param {string} identity - 标识值（身份证/手机号/账号等）
     * @param {string} type - 标识类型: 'idcard' | 'phone' | 'account'
     */
    static async findByIdentity(knex, identity, type = 'idcard') {
        if (!identity) return null;

        if (type === 'idcard') {
            return this.findByIdCard(knex, identity);
        } else if (type === 'credit_code') {
            return this.findByCreditCode(knex, identity);
        } else if (type === 'phone') {
            // 在phones JSON数组中搜索
            const profiles = await knex('profile_entities')
                .whereRaw("phones LIKE ?", [`%${identity}%`]);
            return profiles[0] || null;
        } else if (type === 'account') {
            // 在accounts JSON数组中搜索
            const profiles = await knex('profile_entities')
                .whereRaw("accounts LIKE ?", [`%${identity}%`]);
            return profiles[0] || null;
        }

        return null;
    }

    /**
     * 将源数据关联到档案
     */
    static async linkToProfile(knex, profileId, sourceTable, sourceId, role = 'owner') {
        try {
            await knex('profile_data_links').insert({
                profile_id: profileId,
                source_table: sourceTable,
                source_id: sourceId,
                role
            });
            return true;
        } catch (err) {
            // 忽略唯一约束冲突（已存在的链接）
            if (err.message.includes('UNIQUE constraint')) {
                return false;
            }
            throw err;
        }
    }

    /**
     * 获取档案详情（包含关联数据统计）
     */
    static async getProfile(knex, profileId) {
        const profile = await knex('profile_entities')
            .where('id', profileId)
            .first();

        if (!profile) return null;

        // 解析JSON字段
        profile.phones = JSON.parse(profile.phones || '[]');
        profile.accounts = JSON.parse(profile.accounts || '[]');
        profile.addresses = JSON.parse(profile.addresses || '[]');
        profile.tags = JSON.parse(profile.tags || '[]');
        profile.extra_data = JSON.parse(profile.extra_data || '{}');

        // 获取关联数据统计
        const links = await knex('profile_data_links')
            .where('profile_id', profileId)
            .select('source_table', knex.raw('count(*) as count'))
            .groupBy('source_table');

        profile.linked_data = {};
        for (const link of links) {
            profile.linked_data[link.source_table] = link.count;
        }

        return profile;
    }

    /**
     * 搜索档案
     */
    static async searchProfiles(knex, query, options = {}) {
        const { entity_type, page = 1, pageSize = 20 } = options;

        let builder = knex('profile_entities');

        if (entity_type) {
            builder = builder.where('entity_type', entity_type);
        }

        if (query) {
            builder = builder.where(function () {
                this.where('name', 'like', `%${query}%`)
                    .orWhere('id_card', 'like', `%${query}%`)
                    .orWhere('credit_code', 'like', `%${query}%`)
                    .orWhere('phones', 'like', `%${query}%`);
            });
        }

        const total = await builder.clone().count('* as count').first();
        const items = await builder
            .orderBy('created_at', 'desc')
            .limit(pageSize)
            .offset((page - 1) * pageSize);

        // 解析JSON字段
        for (const item of items) {
            item.phones = JSON.parse(item.phones || '[]');
            item.accounts = JSON.parse(item.accounts || '[]');
            item.tags = JSON.parse(item.tags || '[]');
        }

        return {
            items,
            total: total.count,
            page,
            pageSize
        };
    }

    /**
     * 获取档案统计
     */
    static async getProfileStats(knex, profileId) {
        const links = await knex('profile_data_links')
            .where('profile_id', profileId)
            .select('source_table', 'role', knex.raw('count(*) as count'))
            .groupBy('source_table', 'role');

        return links;
    }


}

module.exports = ProfileService;
